package cn.fan.testfunction.thread;

import java.util.concurrent.*;

/**
 * 模拟线程池框架
 * 这里采用的是jdk  jul ThreadPoolExecutor
 */
public class TaskExecutor {
    /**
     *cpu密集型 N+1   一些内存操作
     * IO密集型 2N  网关类的微服务
     */
    ////这里模拟创建定常队列，然后设置了无界队列长度，避免耗尽资源（存活时间可以设为0）
    private static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
            10, 10, 60,
            TimeUnit.SECONDS, new LinkedBlockingDeque(20), new ThreadPoolExecutor.DiscardPolicy());

    public  void  execute(){
        for(int i=0;i<3;i++) {
            poolExecutor.execute(new TaskMethod());
        }
    }

    public void  submit() throws InterruptedException, ExecutionException {
        // 基于我们自己写的任务代码，构建一个FutureTask，这个FutureTask说白了
        // 其实也是一个任务，只不过是用这个JDK提供的FutureTask封装了我们的任务代码
        FutureTask<String> futureTask =
                new FutureTask<String>(new TaskCallable());
        // 构建一个线程池，线程池里会有一个真正运行任务的线程的
        ExecutorService threadPool = Executors.newFixedThreadPool(1);
        // 把FutureTask任务提交到线程池里去，让线程池里的线程运行我们的任务代码
        threadPool.submit(futureTask);

        // 这个地方我们可以模拟干了一些别的事情，执行了很多别的代码，过了一段时间
        Thread.sleep(1000);

        // 过了一段时间以后，线程池里的线程应该运行完毕我们提交的任务代码了
        // 此时就可以通过FutureTask来获取到那个任务代码运行后的结果
        System.out.println(futureTask.get());
    }
}
